<?php

use W3\Response;
use W3\Request;
use W3\Asset;
use W3\Lang;
use W3\Util;
use W3\Config;
use W3\Blank;
use W3\Json;
use W3\Base;


function widget(...$args)
{
    return Base::widget(...$args);
}

/**
 * 添加javascript
 *
 * @param string  $name 脚本名称 【调用的脚本名称，用于区别其它js，因此不能和其它js文件命名相同】
 * @param string $src   JS路径|JS字符串
 * @param [] $deps   依赖关系数组  加载该脚本前需要加载的其它脚本。默认值：[]
 * @param bool $in_footer   默认值：false，放置在区块中。为true时，会出现在区最下方，但必须有_footer()钩子
 */
function add_script(...$args)
{
    return Asset::addScript(...$args);
}

/**
 * 删除Script
 *
 * @param string  $name 脚本名称
 * @param bool $in_footer   默认值：false
 */
function remove_script(...$args)
{
    return Asset::removeScript(...$args);
}

/**
 * 添加样式表
 *
 * @param string  $name 脚本名称 【调用的脚本名称，用于区别其它CSS，因此不能和其它CSS文件命名相同】
 * @param string $string   CSS路径/CSS字符串
 * @param [] $deps   依赖关系数组  加载该脚本前需要加载的其它脚本。默认值：[]
 */
function add_style(...$args)
{
    return Asset::addStyle(...$args);
}

/**
 * 删除样式
 *
 * @param string  $name 脚本名称
 */
function remove_style(...$args)
{
    return Asset::removeStyle(...$args);
}

/**
 * 获取和设置配置参数
 * @param string|array $name  参数名
 * @param mixed        $value 参数值
 * @return mixed
 */
function config($name = null, $value = null)
{
    if (is_null($name)) {
        return Config::instance();
    }
    if (is_array($name)) {
        return Config::instance()->set($name, $value);
    }
    return 0 === strpos($name, '?') ? Config::instance()->has(substr($name, 1)) : Config::instance()->get($name, $value);
}

/**
 * Cookie管理
 * @param string $name   cookie名称
 * @param mixed  $value  cookie值
 * @param mixed  $option 参数
 * @return mixed
 */
function cookie(string $name, $value = '', $option = null)
{
    if (is_null($value)) {
        // 删除
        Cookie::delete($name);
    } elseif ('' === $value) {
        // 获取
        return 0 === strpos($name, '?') ? Cookie::has(substr($name, 1)) : Cookie::get($name);
    } else {
        // 设置
        return Cookie::set($name, $value, $option);
    }
}

/**
 * 获取当前Request对象实例
 * @return Request
 */
function request() : Request
{
    return Request::instance();
}

/**
 * 创建普通 Response 对象实例
 * @param mixed      $data   输出数据
 * @param int|string $code   状态码
 * @param array      $header 头信息
 * @param string     $type
 * @return Response
 */
function response($data = '', $code = 200, $header = [], $type = 'html') : Response
{
    return Response::create($data, $type, $code)->header($header);
}

/**
 *  将函数挂接到特定挂钩操作上
 *
 *  <code>
 *      // Hooks a function "newLink" on to a "footer" action.
 *      add_action('footer', 'newLink', 10);
 *
 *      function newLink() {
 *          echo '<a href="#">My link</a>';
 *      }
 *  </code>
 *
 * @param string|[]  $action_name    Action name
 * @param mixed   $added_function Added function
 * @param integer $priority       Priority. Default is 10
 * @param array   $args           Arguments
 */
function add_action($name, $callable, int $priority = 10)
{
    if (is_array($name)) {
        foreach ($name as $n) 
		{
            Util::$events[$n][] = ['name' => $n, 'callable' => $callable, 'priority' => $priority];
        }
    } else {
        Util::$events[$name][] = ['name' => $name, 'callable' => $callable, 'priority' => $priority];
    }
}

/**
 * 运行挂接在特定操作挂钩上的函数
 *
 *  <code>
 *      do_action('footer');
 *  </code>
 *
 * @param  string  $name    动作名称
 * @param  array   $args    参数
 * @return mixed
 */
function do_action($name, $call = NULL, $replace = FALSE, ...$args)
{
    # 运行操作
    if (!isset(Util::$events[$name])) {
        return current($args);
    }
    if ($replace) {
        $actions = [end(Util::$events[$name])];
    } else {
        # 按优先级对操作排序
        $actions = Util::arrayMultiSort(Util::$events[$name], 'priority');
    }
    # 应用过滤器
    foreach ($actions as $action) 
	{
        if (isset($call)) {
            $result = call_user_func($action['callable'], $call, ...$args);
        } else {
            $result = call_user_func_array($action['callable'], $args);
        }
        # 过滤器挂接的值
        $args[0] = $result;
    }
    return $result;
}

/**
 * 判断是否存在exists
 *
 * @param string|null $name  变量
 * @return bool
 */
function action_exists($name)
{
    return isset(Util::$events[$name]);
}

/**
 * 获取插件系统参数
 *
 * @param mixed $name 插件名称
 * @return mixed
 * @throws Exception
 */
function plugin($name)
{
    if (!isset(Util::$pluginConfig[$name])) {
        if (!empty(Config::instance()->{'plugin:' . $name}) && false !== ($vars = Json::decode(Config::instance()->{'plugin:' . $name}))) {
            Util::$pluginConfig[$name] = Config::make($vars);
        } else {
            Util::$pluginConfig[$name] = Blank::instance();
            // throw new \Exception(__('插件%s的配置信息没有找到', [$name]), 403);
        }
    }
    return Util::$pluginConfig[$name];
}

/**
 * 翻译给定的信息
 * @param string $name 语言变量名
 * @param array  $vars 动态变量值
 * @param string $lang 语言
 * @return mixed
 */
function __(string $name, array $vars = [], string $lang = ''): string
{
    return Lang::instance()->get($name, $vars, $lang);
}

function _e(...$params)
{
    echo __(...$params);
}

//benchmark("get", function () { (new Base())->a();});
//benchmark("__callStatic", function () { Base::i();});

function benchmark($what, callable $func) 
{
    static $previous;

    if (!$previous) $previous = microtime(true);

    for ($a = 0; $a<=1000000; $a++) { $func(); };

    $now = microtime(true);
    echo sprintf("%s took %.4f seconds", $what, $now - $previous), PHP_EOL;

    $previous = $now;
}

/**
 * 调试函数
 *
 * @example dd($something, $another);
 *
 * @param mixed[] ...,
 */
function dd(...$params)
{
    echo '<pre>';
	print_r(...$params);
    echo '</pre>';
    exit;
}

